package com.zs.blog.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.zs.blog.exception.BusinessException;
import com.zs.blog.model.dto.UserLoginDTO;
import com.zs.blog.model.entity.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.zs.blog.constant.enums.DateConstant.TWELVE_HOURS;
import static com.zs.blog.constant.enums.DateConstant.TWO_HOURS;

/**
 * @Title: JwtUtil
 * @Author zs
 * @Package com.zs.blog.util
 * @Date 2025/4/17 21:51
 * @description: JWT工具类
 */
public class JwtUtil {

    public static final String KEY = "zs-blog";

    public static String generateToken(Map<String, Object> claims, Long time) {
        return JWT.create().withClaim("claims", claims).withExpiresAt(new Date(System.currentTimeMillis() + time)).sign(Algorithm.HMAC256(KEY));
    }

    public static Map<String, Object> parseToken(String token) {
        return JWT.require(Algorithm.HMAC256(KEY)).build().verify(token).getClaim("claims").asMap();
    }

    public static UserLoginDTO refreshToken(String userRefreshToken, String redisRefreshToken) {

        if (StringUtils.isBlank(redisRefreshToken) || !redisRefreshToken.trim().equals(userRefreshToken.trim())) {
            throw new BusinessException("Token已失效!");
        }
        // 解析Token
        Map<String, Object> claims = checkToken(userRefreshToken);
        if (claims == null) {
            throw new BusinessException("Token已失效!");
        }

        return getUserLoginDTO(claims);
    }

    public static Map<String, Object> checkToken(String token) {
        Map<String, Object> data = null;
        try {
            data = parseToken(token);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return data;
    }

    public static UserLoginDTO getToken(User user) {

        Map<String, Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        claims.put("username", user.getUsername());

        return getUserLoginDTO(claims);
    }

    /**
     * 辅助方法
     *
     * @param claims 用户信息
     * @return UserLoginDTO
     */
    private static UserLoginDTO getUserLoginDTO(Map<String, Object> claims) {
        UserLoginDTO userToken = new UserLoginDTO();
        String accessToken = generateToken(claims, TWO_HOURS);
        String refreshToken = generateToken(claims, TWELVE_HOURS);
        userToken.setAccessToken(accessToken);
        userToken.setRefreshToken(refreshToken);

        return userToken;
    }
}
